home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / tex / texsrc.arc / EXTRA.C < prev    next >
C/C++ Source or Header  |  1988-09-14  |  22KB  |  809 lines

  1. /*
  2.  * Hand-coded routines for C TeX.
  3.  * This module should contain any system-dependent code.
  4.  *
  5.  * This code was written by Tim Morgan, drawing from other Unix
  6.  * ports of TeX.
  7.  * hacked up for MEGAMAX-C on ATARI ST by David Dermott
  8.  */
  9.  
  10. /*#define    CATCHINT*/        /* Catch ^C's */
  11. /*#undef    SYSV        */    /* Turn on System V compatibility */
  12. /*#define    BSD    */        /* 4.[23]BSD */
  13.  
  14. #define    EXTERN            /* Actually instantiate globals here */
  15.  
  16. #include "texd.h"
  17. #include <osbind.h>   /* st os routines */
  18. #ifdef    CATCHINT
  19. #include <signal.h>
  20. #endif
  21. #ifdef    BSD
  22. #include <sys/time.h>
  23. #else
  24. #include <time.h>
  25. #endif
  26. /*#if defined(BSD)||defined(SYSV)
  27. #include <sgtty.h>
  28. #endif
  29. */
  30.  
  31. #ifdef    VMS
  32. #define    index    strchr        /* Sys V compatibility */
  33. #endif
  34.  
  35. /* C library stuff that we're going to use */
  36. extern char *strcpy(), *strcat(), *malloc(), *sprintf(), *index(), *getenv();
  37.  
  38. /* Local stuff */
  39. static int gargc;
  40. static char **gargv;
  41. static char texformats[filenamesize], texinputs[filenamesize];
  42. static char texfonts[filenamesize], texpool[filenamesize];
  43. static char my_realnameoffile[filenamesize];
  44. /*static char *texeditvalue = "/usr/ucb/vi +%d %s";*/
  45. static char *texeditvalue = "EMACS.TTP -g%d %s";
  46.  
  47. #define    TRUE    1
  48. #define    FALSE    0
  49.  
  50. #ifdef    CATCHINT
  51. /* If we're catching ^C, come here when one comes in. */
  52. static catchint()
  53. {
  54.     interrupt = 1;
  55.     (void) signal(SIGINT, catchint);
  56. }
  57. #endif
  58.  
  59. /* Do the obvious */
  60. get_date_and_time(minutes, day, month, year)
  61. integer *minutes, *day, *month, *year;
  62. {
  63.     long clock, time();
  64.     struct tm *tmptr, *localtime();
  65.  
  66.     clock = time((long *) 0);
  67.     tmptr = localtime(&clock);
  68.  
  69.     *minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
  70.     *day = tmptr->tm_mday;
  71.     *month = tmptr->tm_mon + 1;
  72.     *year = tmptr->tm_year + 1900;
  73. #ifdef    CATCHINT
  74.     (void) signal(SIGINT, catchint);
  75. #endif
  76.  
  77. }
  78.  
  79. #ifdef    INITEX
  80. /* Read until we pass end of line on the input file, a la Pascal */
  81. readln(f)
  82. FILE *f;
  83. {
  84.     register int c;
  85.  
  86.     do
  87.     c = getc(f);
  88.     while (c != '\n' && c != EOF);
  89. }
  90.  
  91. /* Same as in Pascal --- return TRUE if EOF or next char is newline */
  92. eoln(f)
  93. FILE *f;
  94. {
  95.     register int c;
  96.  
  97.     if (feof(f)) return(TRUE);
  98.     c = getc(f);
  99.     if (c != EOF)
  100.     (void) ungetc(c, f);
  101.     return (c == '\n' || c == EOF);
  102. }
  103. #endif    /* INITEX */
  104.  
  105. static void copy_path(ptr, defptr, override)
  106. char *ptr, *defptr, *override;
  107. {
  108.     if (override) {
  109.     if (strlen(override) >= 1024) {
  110.         (void) fprintf(stderr, "Path too long\n");
  111.         exit(1);
  112.     }
  113.     (void) strcpy(ptr, override);
  114.     }
  115.     else
  116.     (void) strcpy(ptr, defptr);
  117. }
  118.  
  119.  
  120. /* Initialize path variables for loading fonts and things */
  121. setpaths()
  122. {
  123.     copy_path(texformats, TEXFORMATS, getenv("TEXFORMATS"));
  124.     copy_path(texinputs, TEXINPUTS, getenv("TEXINPUTS"));
  125.     copy_path(texfonts, TEXFONTS, getenv("TEXFONTS"));
  126.     copy_path(texpool, TEXPOOL, getenv("TEXPOOL"));
  127. }
  128.  
  129. /*
  130.  *  The following procedure is due to sjc@s1-c.
  131.  *
  132.  *    calledit(filename, fnstart, fnlength, linenumber)
  133.  *
  134.  *  TeX82 can call this to implement the 'e' feature in error-recovery
  135.  *  mode, invoking a text editor on the erroneous source file.
  136.  *  
  137.  *  You should pass to "filename" the first character of the packed array
  138.  *  containing the filename, and to "fnstart" and "fnlength" the index and
  139.  *  length of the filename as it appears inside that array.
  140.  *  
  141.  *  Ordinarily, this invokes "/usr/ucb/vi". If you want a different
  142.  *  editor, create a shell environment variable TEXEDIT containing
  143.  *  the string that invokes that editor, with "%s" indicating where
  144.  *  the filename goes and "%d" indicating where the decimal
  145.  *  linenumber (if any) goes. For example, a TEXEDIT string for a
  146.  *  variant copy of "vi" might be:
  147.  *  
  148.  *    setenv TEXEDIT "/usr/local/bin/vi +%d %s"
  149.  *  
  150.  */
  151.  
  152. calledit(filename, fnstart, fnlength, linenumber)
  153. ASCIIcode filename[];
  154. poolpointer fnstart;
  155. integer fnlength, linenumber;
  156. {
  157.     char *temp, *command, c;
  158.     int sdone, ddone, i;
  159. /* close all input files */
  160.         for (i=1;i<= inopen;i++)fclose(inputfile[i]);
  161. /* so they can be editted */
  162.     freemem();/* free some memory*/
  163.     sdone = ddone = 0;
  164.     filename += fnstart;
  165.  
  166.     /* Replace default with environment variable if possible. */
  167.     if (NULL != (temp = getenv("TEXEDIT")))
  168.     texeditvalue = temp;
  169.  
  170.     /* Make command string containing envvalue, filename, and linenumber */
  171.     if (NULL ==
  172.     (command = (char *) malloc((unsigned) strlen(texeditvalue) + (int)fnlength
  173.                    + 25))) {
  174.     (void) fprintf(stderr, "! Not enough memory to issue editor command\n");
  175.     exit(1);
  176.     }
  177.     temp = command;
  178.     while ((c = *texeditvalue++) != '\0') {
  179.     if (c == '%') {
  180.         switch (c = *texeditvalue++) {
  181.         case 'd':
  182.         if (ddone) {
  183.             (void) fprintf(stderr,
  184.             "! Line number cannot appear twice in editor command\n");
  185.             exit(1);
  186.         }
  187.         (void) sprintf(temp, "%d", (int)linenumber);
  188.         while (*temp != '\0')
  189.             temp++;
  190.         ddone = 1;
  191.         break;
  192.         case 's':
  193.         if (sdone) {
  194.             (void) fprintf(stderr,
  195.               "! Filename cannot appear twice in editor command\n");
  196.             exit(1);
  197.         }
  198.         i = 0;
  199.         while (i < fnlength)
  200.             *temp++ = filename[i++];
  201.         sdone = 1;
  202.         break;
  203.         case '\0':
  204.         *temp++ = '%';
  205.         texeditvalue--;    /* Back up to \0 to force termination. */
  206.         break;
  207.         default:
  208.         *temp++ = '%';
  209.         *temp++ = c;
  210.         break;
  211.         }
  212.     }
  213.     else
  214.         *temp++ = c;
  215.     }
  216.     *temp = '\0';
  217.     /* Execute command. */
  218.     if (system(command)) 
  219.     (void) fprintf(stderr, "! Trouble executing command %s\n", command);
  220.  
  221.     /* Quit, indicating TeX found an error */
  222.     exit(1);
  223. }
  224.  
  225.  
  226. /*
  227.  * Change a Pascal-like filename into a C-like string.
  228.  * If running on a non-ASCII system, will have to use xchr[]
  229.  * array to convert from internal character set (in the "nameoffile"
  230.  * array) into the enternal character set (in "realnameoffile").
  231.  * "nameoffile" is an array indexed starting with 1, so we add 1
  232.  * to all references to point to the first character in the name.
  233.  */
  234. static packrealnameoffile(prefix)
  235. char *prefix;
  236. {
  237.     register char *cp, *p, *q;
  238.  
  239.     p = prefix;
  240.     for (q = my_realnameoffile; p && *p && *p != ';'; *q++ = *p++);
  241.     if (prefix && *prefix)
  242.     *q++ = '\\';
  243.     for (cp = nameoffile+1, p = realnameoffi + 1; *cp != ' ' && *cp;)
  244. #ifdef    NONASCII
  245.     *q++ = xchr[*p++ = *cp++];
  246. #else
  247.     *q++ = (*p++ = *cp++);
  248. #endif
  249.     *p = ' ';
  250.     *q = '\0';
  251. }
  252.  
  253. /* Open an input file f */
  254. Openin(f, pathspec,fmode)
  255. FILE **f;
  256. int pathspec;
  257. char fmode[];
  258. {
  259.     register char *prefix, *nprefix;
  260.     register char *cp;
  261. /*printf("name %s mode %s path %d  ",&nameoffile[1],fmode,pathspec);*/
  262.     switch (pathspec) {
  263.     case inputpathspec:
  264.     case readpathspec:
  265.     prefix = texinputs;
  266.     break;
  267.     case fontpathspec:
  268.     prefix = texfonts;
  269.     break;
  270.     case poolpathspec:
  271.     prefix = texpool;
  272.     break;
  273.     case fmtpathspec:
  274.     prefix = texformats;
  275.     break;
  276.     default:            /* "Can't" happen */
  277.     (void) fprintf(stderr, "INTERNAL CONFUSION---IMPLEMENTATION ERROR\n");
  278.     exit(1);
  279.     }
  280. /*printf(" %s \n",prefix);*/
  281.     if ((nameoffile[2] == ':')||(nameoffile[1] == '/')) {/* Absolute pathname */
  282.     for (cp = nameoffile+1; *cp && *cp != ' '; ++cp);
  283.     *cp = '\0';
  284. /*printf("absolute %s\n",nameoffile);*/
  285.     cnvtfn(nameoffile+1);
  286.     if (*f = fopen(nameoffile+1, fmode)) {
  287.         (void) strcpy(realnameoffi + 1, nameoffile+1);
  288.         (void) strcat(realnameoffi + 1, " ");
  289.         if (pathspec == fontpathspec)
  290.         tfmtemp = getc(*f);    /* Simulate readahead */
  291.         return (1);
  292.     }
  293.     return (0);
  294.     }
  295.     /* Else relative pathname */
  296.     while (prefix) {
  297.     packrealnameoffile(prefix);
  298. /*printf("try %s  %s\n",my_realnameoffile,prefix);*/
  299.     cnvtfn(my_realnameoffile);
  300.     *f = fopen(my_realnameoffile, fmode);
  301.     if (*f) {
  302.         (void) strcpy(realnameoffi + 1, my_realnameoffile);
  303.         (void) strcat(realnameoffi + 1, " ");
  304.         if (pathspec == fontpathspec)
  305.         tfmtemp = getc(*f);    /* Simulate Pascal readahead */
  306.         return (1);
  307.     }
  308.     nprefix = index(prefix, ';');
  309.     if (nprefix)
  310.         prefix = nprefix + 1;
  311.     else
  312.         break;
  313.